package com.pactera.mavenweb.daoimpl;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.pactera.mavenweb.dao.IGenericDao;
import com.pactera.mavenweb.dto.Page;

public abstract class GenericDaoImpl<T> implements IGenericDao<T> {

	private Class<T> entityClass;
	
	public GenericDaoImpl(Class<T> clazz) {
		this.entityClass = clazz;
	}
	
	/**
	 * 使用注解方式，注入SessionFactory
	 */
	@Autowired
	private SessionFactory sessionFactory;
	
//	@Override
	@SuppressWarnings("unchecked")
	public void insert(T t) {
		sessionFactory.getCurrentSession().saveOrUpdate(t);
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public void delete(T t) {
		sessionFactory.getCurrentSession().delete(t);
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public void delete(String id) {
		
		String hql = "delete from " + entityClass.getSimpleName() + " where id = '" + id + "'";
		
		sessionFactory.getCurrentSession().createCriteria(hql);
		
		T t = (T) queryById(id);
		delete(t);
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public void delete(int id) {
		
		String hql = "delete from " + entityClass.getSimpleName() + " where id = " + id;
		
		sessionFactory.getCurrentSession().createCriteria(hql);
		
		T t = (T) queryById(id);
		if(t != null) {
			delete(t);
		}
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public void update(T t) {
		sessionFactory.getCurrentSession().update(t);
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public T queryById(String id) {
		return (T) sessionFactory.getCurrentSession().get(entityClass, id);
	}
	
//	@Override
	@SuppressWarnings("unchecked")
	public T queryById(int id) {
		return (T) sessionFactory.getCurrentSession().get(entityClass, id);
	}
	
//	@Override
	public List<T> queryAll() {
		String hql = "from " + entityClass.getSimpleName();
		return queryForList(hql, null);
	}
	
//	@Override
	public List<T> queryAllByPage(Page page) {
		String hql = "from " + entityClass.getSimpleName();
		return queryForListByPage(hql, null, page);
	}
	
	@SuppressWarnings("unchecked")
	public T queryForObject(String hql, Object[] params) {
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		setQueryParams(query, params);
		return (T) query.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public T queryForTopObject(String hql, Object[] params) {
//		Query query = sessionFactory.getCurrentSession().createQuery(hql);
//		setQueryParams(query, params);
//		
//		List<T> list = queryForList(hql, params, 1).get(0);
//		List<T> list = queryForList(hql, params, 0);
//		if(list.size() > 1) {
//			
//		}
		return queryForList(hql, params, 0).get(0);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> queryForList(String hql, Object[] params) {
		sessionFactory.getCurrentSession().createQuery(hql);
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		setQueryParams(query, params);
		return query.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<T> queryForListByPage(String hql, Object[] params, Page page) {
		int num = (page.getPage() - 1) * page.getNum();
		
		sessionFactory.getCurrentSession().createQuery(hql);
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		
		query.setFirstResult(num);
		query.setMaxResults(page.getNum());
		
		setQueryParams(query, params);
		return query.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<T> queryForList(final String hql, final Object[] params,
			final int recordNum) {
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		query.setFirstResult(recordNum);
		setQueryParams(query, params);
		
		return query.list();
	}
	
	private void setQueryParams(Query query, Object[] params) {
		if (null == params) {
			return;
		}
		for (int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
	}
}
